package model.components.links.link;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;

public class PhysicalLink extends Link
{	
	public static final String NAME_PREFIX = "PhysicalLink";
	
	private LinkedHashMap< VirtualLink, BandwidthBackupFlag > virtualLinksBandwidthsBackupFlags;
	public LinkedHashMap< VirtualLink, BandwidthBackupFlag > getVirtualLinksBandwidthsBackupFlags(){ return virtualLinksBandwidthsBackupFlags; }
	public void setVirtualLinksBandwidthsBackupFlags( LinkedHashMap< VirtualLink, BandwidthBackupFlag > virtualLinksBandwidthsBackupFlags ){ this.virtualLinksBandwidthsBackupFlags = virtualLinksBandwidthsBackupFlags; }
	
	private int availableBandwidth;
	public int getAvailableBandwidth(){ return availableBandwidth; }
	public void setAvailableBandwidth( int availableBandwidth ){ this.availableBandwidth = availableBandwidth; }
	
	private int distance;
	public int getDistance(){ return distance; }
	public void setDistance( int distance ){ this.distance = distance; }
	
	public PhysicalLink( String networkName, int number, int bandwidth, int distance )
	{
		super( networkName, PhysicalLink.NAME_PREFIX, number, bandwidth, "/icons/physicalLink.png" );
		
		this.setVirtualLinksBandwidthsBackupFlags( new LinkedHashMap< VirtualLink, BandwidthBackupFlag >() );
		this.setAvailableBandwidth( bandwidth );
		this.setDistance( distance );
	}
	
	@Override
	public PhysicalLink getCopy()
	{
		PhysicalLink physicalLink = new PhysicalLink( this.getNetworkName(), this.getNumber(), this.getBandwidth(), this.getDistance() );
		physicalLink.setNamePrefix( this.getNamePrefix() );
		physicalLink.setName( this.getName() );
		physicalLink.setFirstNode( this.getFirstNode().getCopy() );
		physicalLink.setSecondNode( this.getSecondNode().getCopy() );
		physicalLink.setAvailableBandwidth( this.getAvailableBandwidth() );
		physicalLink.setTimeStamp( this.getTimeStamp() );
		physicalLink.setSelected( this.isSelected() );
		physicalLink.setVirtualLinksBandwidthsBackupFlags( this.getCopyVirtualLinksBandwidthsBackupFlags() );
		
		return physicalLink;
	}
	private LinkedHashMap< VirtualLink, BandwidthBackupFlag > getCopyVirtualLinksBandwidthsBackupFlags()
	{
		LinkedHashMap< VirtualLink, BandwidthBackupFlag > copyVirtualLinksBandwidthsBackupFlags = new LinkedHashMap< VirtualLink, BandwidthBackupFlag >();
		Iterator< Entry< VirtualLink, BandwidthBackupFlag > > virtualLinksBandwidthsBackupFlagsIterator = this.getVirtualLinksBandwidthsBackupFlags().entrySet().iterator();
		
		while( virtualLinksBandwidthsBackupFlagsIterator.hasNext() )
		{
			Entry< VirtualLink, BandwidthBackupFlag > virtualLinkBandwidthBackupFlag = virtualLinksBandwidthsBackupFlagsIterator.next();
			copyVirtualLinksBandwidthsBackupFlags.put( virtualLinkBandwidthBackupFlag.getKey().getCopy(), virtualLinkBandwidthBackupFlag.getValue() );
		}
		
		return copyVirtualLinksBandwidthsBackupFlags;
	}
	
	public void put( VirtualLink virtualLink, int bandwidth, int backupFlag )
	{	
		this.getVirtualLinksBandwidthsBackupFlags().put( virtualLink, new BandwidthBackupFlag( bandwidth, backupFlag ) );
		this.setAvailableBandwidth( this.getAvailableBandwidth() - bandwidth );
	}
	
	public void remove( VirtualLink removeVirtualLink )
	{
		Iterator< Entry< VirtualLink, BandwidthBackupFlag > > virtualLinksBandwidthsBackupFlagsIterator = this.getVirtualLinksBandwidthsBackupFlags().entrySet().iterator();
		VirtualLink virtualLink = null;
		int bandwidth = 0;
		
		while( virtualLinksBandwidthsBackupFlagsIterator.hasNext() )
		{
			Entry< VirtualLink, BandwidthBackupFlag > virtualLinkBandwidthBackupFlag = virtualLinksBandwidthsBackupFlagsIterator.next();
			virtualLink = virtualLinkBandwidthBackupFlag.getKey();
			bandwidth = virtualLinkBandwidthBackupFlag.getValue().getBandwidth();
			 
			if( removeVirtualLink.equals( virtualLink ) )
				break;
		}
		
		this.getVirtualLinksBandwidthsBackupFlags().remove( virtualLink );
		this.setAvailableBandwidth( this.getAvailableBandwidth() + bandwidth );
	}
	
}
